#include "Camera.h"
#include "Matrix.h"
#include <windows.h>
#include <gl\gl.h>
#define _USE_MATH_DEFINES
#include <cmath>
#define PI (float)M_PI

Camera::Camera(void)
{
	position = Vector3(0, 0, 0);
	angleX = 0;
	angleY = 0;
}

Camera::~Camera()
{

}

Vector3 Camera::Position(void)
{
	return position;
}

Vector3 Camera::GetLookingDirection(void)
{
	Vector3 direction(0, 0, -1);
	Matrix44 rotateX = Matrix44::RotateX(-angleX);
	Matrix44 rotateY = Matrix44::RotateY(-angleY);

	direction = rotateX * direction;
	direction = rotateY * direction;
	return direction;
}

void Camera::MoveZ(float step)
{
	Vector3 v(0, 0, 1);
	Matrix44 m;
	m = Matrix44::RotateX(-angleX);
	v = m * v;
	m = Matrix44::RotateY(-angleY);	
	v = m * v;
	position += v * step;
}

void Camera::MoveY(float step)
{
	Vector3 v(0, 1, 0);	
	Matrix44 m;
	m = Matrix44::RotateX(-angleX);
	v = m * v;
	m = Matrix44::RotateY(-angleY);	
	v = m * v;
	position += v * step;
}

void Camera::MoveX(float step)
{
	Vector3 v(1, 0, 0);
	Matrix44 m;
	m = Matrix44::RotateX(-angleX);
	v = m * v;
	m = Matrix44::RotateY(-angleY);	
	v = m * v;
	position += v * step;
}

void Camera::RotateX(float angle)
{
	if(angleX + angle >= PI * 0.5)
	{
		angleX = PI * 0.5f;
		return;
	}
	if(angleX + angle <= -PI * 0.5)
	{
		angleX = -PI * 0.5f;
		return;
	}
	angleX += angle;
}

void Camera::RotateY(float angle)
{
	angleY += angle;
}

void Camera::Update(void)
{
	glRotated((180 / PI) * angleX, 1, 0, 0);
	glRotated((180 / PI) * angleY, 0, 1, 0);	
	glTranslated(-position.x, -position.y, -position.z);
}

Matrix44 Camera::GetMatrix(void)
{
	Matrix44 m = Matrix44::I();
	m = m * Matrix44::RotateX(angleX);
	m = m * Matrix44::RotateY(angleY);
	m = m * Matrix44::Translate(-1.0 * position);
	return m;
}

Matrix44 Camera::GetInvertedMatrix(void)
{
	Matrix44 m = Matrix44::I();	
	m = m * Matrix44::Translate(position);
	m = m * Matrix44::RotateY(-angleY);
	m = m * Matrix44::RotateX(-angleX);
	return m;
}

void Camera::SetPosition(Vector3 &position)
{
	this->position = position;
}